<?php
/**
 * Created by PhpStorm.
 * User: My
 * Date: 2018/9/3
 * Time: 15:42
 */

namespace App\Http\Helper;

use App\Models\LogHelper;
use App\Services\DimensionAlgoHelper;
use App\Services\IdEncryptService;
use TestingDetailService;
use TestingPartService;
use TestingPartRecordService;
use WechatUserService;
use TestingItemService;
use TestingAlgoHelper;
use TestingConfig;
use DB;
use UserRecordService;
use JzNutritionistService;
use TestingChannelService;
use TestingSyncOrderService;
use TestingQuestionService;

class DimensionHelper
{
    /**
     * 获取维度测评的题目信息
     * @param $uid
     * @param $tid
     * @param $type
     * @param $orderId
     * @param $nutriId
     * @return array
     */
    public static function dimensionQuestionInfo($uid, $tid, $type, $orderId, $nutriId) {
        $data = [
            'dimension_info' => [],
            'result' => [],
            'is_finish' => false,
            'redirect_uri' => '',
            'question_list' => [],
            'pop' => [
                'show_pop' => 0
            ]
        ];

        //获取最新的维度测评的信息
        $partRecord = TestingPartRecordService::getLastOneByUid($uid, $tid);
        //获取当前测评的最大维度
        $maxDimension = TestingPartService::getMaxDimensionByTid($tid);

        //1、如果存在维度测评的信息，而且不是最大的维度
        // 则直接获取下一维度的相关信息, 返回给前端
        if ($partRecord && $partRecord['dimension'] < $maxDimension) {
            $dimensionInfo = TestingPartService::getOneByTidAndDimension($tid, $partRecord['dimension'] + 1);
            //获取当前维度的结果信息
            $resultData = json_decode($partRecord['result'], true);
            $data['result'] = formatArrValue($resultData, 'result', []);
            $data['dimension_info'] = $dimensionInfo ? self::formatDimension($dimensionInfo) : [];
            //取出下一维度的题目
            $data['question_list'] = self::getDimensionQuestion($tid, $dimensionInfo['dimension']);
            return $data;
        } else {    //如果不存在维度测评信息，或者已经完整的答了一次题
            $user = WechatUserService::getByUid($uid);
            if (!$user) {
                $user = [
                    'channel_code' => '',
                    'uid' => $uid,
                ];
            }
            if ($nutriId && $type != 'retry') {
                //如果有营养师信息，则判断是否有在这个营养师下的做的测评，没有就要重做
                $userRecord = UserRecordService::getLastOneByUidTidNutriId($uid, $tid, $nutriId);
                if ($userRecord) { //有记录的话，直接显示结果页
                    $data['is_finish'] = true;
                    $resultData = json_decode($partRecord['result'], true);
                    $data['redirect_uri'] = formatArrValue($resultData, 'redirect_uri');

                    return $data;
                }
            } elseif ($partRecord && $type != 'retry') {
                //如果存在记录，且不是重做
                $data['is_finish'] = true;
                $resultData = json_decode($partRecord['result'], true);
                $data['redirect_uri'] = formatArrValue($resultData, 'redirect_uri');

                return $data;
            }

            //其他情况，显示第一维度的信息
            //判断是否弹窗
            list($isPop, $usePop) = self::popType($user);
            if ($isPop) {
                $data['pop']['show_pop'] = $usePop;
            }

            $dimensionInfo = TestingPartService::getOneByTidAndDimension($tid, 1);
            $data['dimension_info'] = $dimensionInfo ? self::formatDimension($dimensionInfo) : [];
            //取出第一维度的题目信息
            $data['question_list'] = self::getDimensionQuestion($tid, $dimensionInfo['dimension']);

            return $data;
        }
    }

    /**
     * 获取测评结果信息
     * @param $uid
     * @param $tid
     * @return array
     */
    public static function dimensionResult($uid, $tid) {
        $data = [
            'part_one' => [],
            'part_two' => [],
        ];

        $partRecord = TestingPartRecordService::getLastOneByUid($uid, $tid);
        $maxDimension = TestingPartService::getMaxDimensionByTid($tid);

        if ($partRecord['dimension'] != $maxDimension) {
            return [false, 'five_dimension.dimension_error'];
        }

        $resultData = json_decode($partRecord['result'], true);
        $data['part_one'] = formatArrValue($resultData, 'part_one', []);
        $data['part_two'] = formatArrValue($resultData, 'part_two', []);

        return [true, $data];
    }

    /**
     * 提交用户的答题信息
     * @param $uid
     * @param $tid
     * @param $orderId
     * @param $nutriId
     * @param $virtualOrderId
     * @param $dimension
     * @param $answers
     * @return array|bool
     * @throws \App\Exceptions\UserException
     */
    public static function dimensionSubmit($uid, $tid, $orderId, $nutriId, $virtualOrderId, $dimension, $answers) {
        if ($uid && $tid && $dimension && $answers) {
            // $data-插入user_record数据库的值 $partRecordRes-插入到part_record的记录的值
            $data = $partRecordRes = [];
            $partRecord = TestingPartRecordService::getLastOneByUid($uid, $tid);
            $maxDimension = TestingPartService::getMaxDimensionByTid($tid);

            if (!self::checkDimension($partRecord, $dimension, $maxDimension)) {
                LogHelper::log("用户答题维度异常 uid => " . $uid . ' tid => ' . $tid);
                return [false, 'five_dimension.dimension_error'];
            }

            if (!$testingInfo = TestingDetailService::getById($tid)) {
                return [false, 'eid_tid_not_match'];
            }

            $currentDimensionInfo = TestingPartService::getOneByTidAndDimension($tid, $dimension);
            if ($dimension + 1 <= $maxDimension) {
                $nextDimensionInfo = TestingPartService::getOneByTidAndDimension($tid, $dimension + 1);
            }
            $partRecordRes['answers'] = $answers;
            $partRecordRes['uid'] = $uid;
            $partRecordRes['tid'] = $tid;
            $partRecordRes['dimension'] = $dimension;
            $partRecordRes['evaluation_times'] = $dimension != 1 ? $partRecord['evaluation_times'] : ($partRecord ? $partRecord['evaluation_times'] + 1 : 1);

            $nextDimensionName = isset($nextDimensionInfo) ? $nextDimensionInfo['name'] : '';
            //计算了当前维度的结果信息
            $res['result'] = $partRecordRes['result']['result'] = self::getDimensionStageResult($currentDimensionInfo, $maxDimension, $nextDimensionName);

            //用户完成五维答题
            if ($dimension == $maxDimension) {
                $res['is_finish'] = true;
                //把测评的结果拼起来
                $hisAnswers = '';
                $partRecords = TestingPartRecordService::getByUidAndTimes($uid, $tid, $partRecord['evaluation_times']);
                foreach ($partRecords as $partRecordItem) {
                    if ($partRecordItem['dimension'] == 1) {
                        $hisAnswers = $partRecordItem['answers'];
                    } else {
                        $hisAnswers .= '##' . $partRecordItem['answers'];
                    }
                }
                $answers = $hisAnswers . '##' . $answers;

                //计算测评的结果
                $dimensionAlgo = new DimensionAlgoHelper($tid);
                $result = $dimensionAlgo->calculate($answers);

                if (!$orderId && !$nutriId) {
                    //获取用户手机号同步的信息
                    list($orderId, $nutriId) = self::getUserInfo($uid);
                }
                $data['answers'] = $answers;
                $data['uid'] = $uid;
                $data['order_id'] = $orderId;
                $data['nutritionist_id'] = $nutriId;
                $data['virtual_oid'] = $virtualOrderId;

                $data['nick_name']= WechatUserService::getNickNameByUid($uid);
                $data['testing_name'] = $testingInfo['name'];
                $data['tid'] = $tid;

                $data['score'] = $result['score'];
                $data['final_answers'] = $partRecordRes['final_answers'] = $dimensionAlgo->getAnswerStr();
                $data['conclusion'] = $result['conclusion'];
                $data['testtime'] = time();

                if (in_array($tid, BusinessHelper::getDimensionNewResultTids())) {
                    //使用新版的结果页的，96
                    $partRecordRes['result']['answer'] = $dimensionAlgo->getMarkInfo();
                    $partRecordRes['result']['score'] = $result['score'];
                    $res['redirect_uri'] = $partRecordRes['result']['redirect_uri'] = self::getRedirectUri($uid, $tid);
                } else {
                    $partRecordRes['result']['part_one'] = self::getResultPartOne($result);
                    $partRecordRes['result']['part_two'] = self::getResultPartTwo($dimensionAlgo->getMarkInfo());
                }

                //记录测评结果和部分结果
                DB::transaction(function () use ($data, $partRecordRes, $tid, $uid,$virtualOrderId) {
                    $saveResult = UserRecordService::stroeResult($data);
                    if($virtualOrderId){
                        LogHelper::log('通知结果回调===>virtual_oid:'.$virtualOrderId);
                        UserRecordService::syncVirtualOrderRecord($saveResult);
                    }
                    TestingDetailService::updataTestTimes($data['tid']);
                    //记录部分测评结果信息
                    $partRecordRes['result'] = json_encode($partRecordRes['result'], JSON_UNESCAPED_UNICODE);
                    TestingPartRecordService::store($partRecordRes);
                }, 5);
            } else {
                $dimensionInfo = TestingPartService::getOneByTidAndDimension($tid, $dimension + 1);
                $res['dimension_info'] = $dimensionInfo ? self::formatDimension($dimensionInfo) : [];
                $res['is_finish'] = false;
                //获取下一维度的题目信息
                $res['question_list'] = self::getDimensionQuestion($tid, $dimensionInfo['dimension']);
                //记录部分测评结果信息
                $partRecordRes['result'] = json_encode($partRecordRes['result'], JSON_UNESCAPED_UNICODE);
                TestingPartRecordService::store($partRecordRes);
            }
            return [true, $res];
        } else {
            LogHelper::log('参数异常 uid ==> ' . $uid . ' tid ==> ' . $tid . ' dimension ==>' . $dimension . ' answer ==> ' . $answers);
            return [false, 'param_error'];
        }
    }

    /**
     * 获取结果页第一部分的信息
     * @param $info
     * @return array
     */
    private static function getResultPartOne($info) {
        return [
            'score' => $info['score'],
            'conclusion' => $info['conclusion'],
        ];
    }

    /**
     * 获取结果页第二部分的信息
     * @param $markInfo
     * @return array
     */
    private static function getResultPartTwo($markInfo) {
        $stature = json_decode(TestingConfig::getValue('five.dimension.pay.stature_v2', '{}'), true);
        $sexKey = $markInfo['sex']['weight'];
        $statureKey = $markInfo['stature']['weight'];

        return [
            'stature_img' => $stature['img'][$sexKey][$statureKey],
            'stature_text' => $stature['text'][$statureKey],
        ];
    }

    /**
     * 获取结果需要的答案的信息
     * @param $markInfo
     * @return array
     */
    private static function getResultAnswer($markInfo) {
        $sexKey = $markInfo['sex']['weight'];
        $statureKey = $markInfo['stature']['weight'];

        return [
            'gender' => $sexKey,
            'stature' => $statureKey,
        ];
    }

    /**
     * 获取当前维度的题目信息
     * @param $tid
     * @param int $dimension
     * @return array
     */
    private static function getDimensionQuestion($tid, $dimension) {
        $data = [];
        $part = TestingPartService::getOneByTidAndDimension($tid, $dimension);
        $itemIds = json_decode($part['testing_item_ids'], true);
        $list = TestingQuestionService::getListByIdsOrderByParam($itemIds);
        foreach ($list as $item) {
            $data[] = [
                'id' => $item['id'],
                'title' => $item['title'],
                'questionType' => $item['question_type'],
                'options' => json_decode($item['options'], true),
                'blankType' => $item['blank_type']
            ];
        }
        return $data;
    }

    /**
     * 获取维度的阶段结果信息
     * @param $currentDimension
     * @param $maxDimension
     * @param $nextDimensionName
     * @return array
     */
    private static function getDimensionStageResult($currentDimension, $maxDimension, $nextDimensionName) {
        $config = json_decode($currentDimension['config'], true);
        return [
            'cur_name' => $currentDimension['name'],
            'cur_dimension' => $currentDimension['dimension'],
            'max_dimension' => $maxDimension,
            'result_tips' => $config['result_tips'],
            'next_name' => $nextDimensionName,
        ];
    }

    /**
     * 判断用户答题的维度是否正常
     * @param array $partRecord 用户最新的答题记录
     * @param int $dimension 当前完成的维度
     * @param int $maxDimension 最大维度
     * @return bool
     */
    private static function checkDimension($partRecord, $dimension, $maxDimension) {
        return ($dimension == 1 && (!$partRecord || ($partRecord && $partRecord['dimension'] == $maxDimension)))
            || $partRecord['dimension'] + 1 == $dimension;
    }

    /**
     * 格式化维度信息
     * @param $dimension
     * @return array
     */
    private static function formatDimension($dimension) {
        $config = json_decode($dimension['config'], true);
        return [
            'dimension' => $dimension['dimension'],
            'name' => $dimension['name'],
            'tips' => $config['tips'],
            'tid' => $dimension['tid'],
        ];
    }

    /**
     * 判断是否弹窗，填写手机号
     * @param $user
     * @return array
     */
    private static function popType($user) {
        if (!TestingSyncOrderService::getOneByUid($user['uid'])) {
            $channel = TestingChannelService::getOneByCode($user['channel_code']);
            if ($channel) {
                $config = json_decode($channel['config'], true);
                if (isset($config['show_pop']) && $config['show_pop']) {
                    return [true, $config['show_pop']];
                }
            }
        }
        return [false, 0];
    }

    /**
     * 获取渠道的配置信息
     * @param $uid
     * @param $tid
     * @return string
     */
    private static function getRedirectUri($uid, $tid) {
        if ($user = WechatUserService::getByUid($uid)) {
            $channel = TestingChannelService::getOneByCode($user['channel_code']);
            if ($channel) {
                $config = json_decode($channel['config'], true);
                if ($config && $config['redirect_uri'] && is_array($config['redirect_uri'])) {
                    $url = $config['redirect_uri'][0];  //0就作为默认的吧
                    if (isset($config['redirect_uri'][$tid])) {
                        $url = $config['redirect_uri'][$tid];
                    }
                    $uid = IdEncryptService::encryption($uid, 'encode');
                    $tid = IdEncryptService::encryption($tid, 'encode');
                    return ParamParseHelper::parse($url, $uid, $tid);
                }
            }
        }
        return '';
    }

    /**
     * 测评同步
     * @param $uid
     * @return array
     */
    private static function getUserInfo($uid) {
        $syncOrder = TestingSyncOrderService::getOneByUid($uid);
        if (!$syncOrder) {
            LogHelper::log("不存在用户的同步信息 uid:" . $uid);
            return [null, null];
        }

        return [$syncOrder['order_id'], $syncOrder['nutritionist_id']];
    }
}